package com.murong.ai.coder.infrastructure.view;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;

import javax.swing.*;
import javax.swing.table.DefaultTableModel;
import java.awt.*;
import java.io.File;
import java.util.*;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.nio.file.Files;
import java.nio.file.Paths;

public class JsonGeneratorWindow extends JFrame {
    private JTextField filePathField;
    private JButton browseButton;
    private JButton generateButton;
    private JTextArea resultArea;
    private final ObjectMapper objectMapper;
    private Set<String> processedClasses;

    public JsonGeneratorWindow() {
        objectMapper = new ObjectMapper();
        objectMapper.enable(SerializationFeature.INDENT_OUTPUT);
        processedClasses = new HashSet<>();
        initUI();
    }

    private void initUI() {
        setTitle("JSON生成器");
        setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        setSize(1200, 800);
        setLocationRelativeTo(null);

        // 主面板
        JPanel mainPanel = new JPanel(new BorderLayout(10, 10));
        mainPanel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));

        // 顶部面板
        JPanel topPanel = new JPanel(new BorderLayout(5, 0));
        filePathField = new JTextField();
        browseButton = new JButton("浏览");
        generateButton = new JButton("生成JSON");
        
        JPanel buttonPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT));
        buttonPanel.add(browseButton);
        buttonPanel.add(generateButton);
        
        topPanel.add(new JLabel("Java类文件路径: "), BorderLayout.WEST);
        topPanel.add(filePathField, BorderLayout.CENTER);
        topPanel.add(buttonPanel, BorderLayout.EAST);
        
        // 结果区域
        resultArea = new JTextArea();
        resultArea.setFont(new Font(Font.MONOSPACED, Font.PLAIN, 12));
        JScrollPane scrollPane = new JScrollPane(resultArea);

        mainPanel.add(topPanel, BorderLayout.NORTH);
        mainPanel.add(scrollPane, BorderLayout.CENTER);

        // 添加事件监听
        browseButton.addActionListener(e -> browseFile());
        generateButton.addActionListener(e -> generateJson());

        getContentPane().add(mainPanel);
        setVisible(true);
    }

    private void browseFile() {
        JFileChooser fileChooser = new JFileChooser();
        fileChooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
        fileChooser.setFileFilter(new javax.swing.filechooser.FileFilter() {
            public boolean accept(File f) {
                return f.getName().toLowerCase().endsWith(".java") || f.isDirectory();
            }

            public String getDescription() {
                return "Java Files (*.java)";
            }
        });

        int result = fileChooser.showOpenDialog(this);
        if (result == JFileChooser.APPROVE_OPTION) {
            filePathField.setText(fileChooser.getSelectedFile().getAbsolutePath());
        }
    }

    private void generateJson() {
        String filePath = filePathField.getText().trim();
        if (filePath.isEmpty()) {
            JOptionPane.showMessageDialog(this, "请选择Java类文件！", "错误", JOptionPane.ERROR_MESSAGE);
            return;
        }

        try {
            processedClasses.clear(); // 清除已处理的类记录
            String content = new String(Files.readAllBytes(Paths.get(filePath)));
            List<Map<String, String>> fields = parseJavaFile(content, filePath);
            String json = objectMapper.writeValueAsString(fields);
            resultArea.setText(json);
        } catch (Exception e) {
            JOptionPane.showMessageDialog(this,
                    "生成JSON失败：" + e.getMessage(),
                    "错误",
                    JOptionPane.ERROR_MESSAGE);
            e.printStackTrace();
        }
    }

    private List<Map<String, String>> parseJavaFile(String content, String filePath) throws Exception {
        List<Map<String, String>> fields = new ArrayList<>();
        
        // 添加基本字段
        addBasicFields(fields);

        // 解析类名
        Pattern classPattern = Pattern.compile("public\\s+class\\s+(\\w+)");
        Matcher classMatcher = classPattern.matcher(content);
        if (classMatcher.find()) {
            String className = classMatcher.group(1);
            if (processedClasses.contains(className)) {
                return fields; // 避免循环引用
            }
            processedClasses.add(className);
        }

        // 解析导入语句
        Map<String, String> imports = new HashMap<>();
        Pattern importPattern = Pattern.compile("import\\s+([\\w\\.]+)\\.([\\w]+);");
        Matcher importMatcher = importPattern.matcher(content);
        while (importMatcher.find()) {
            String packageName = importMatcher.group(1);
            String importedClass = importMatcher.group(2);
            imports.put(importedClass, packageName + "." + importedClass);
        }

        // 解析字段
        Pattern fieldPattern = Pattern.compile(
            "(?:/\\*+\\s*([^*]*?)\\s*\\*+/\\s*)?" +  // 可选的块注释，捕获注释内容
            "(?:@ECPDict\\s*\\(([^)]*)\\)\\s*)?" +   // 可选的@ECPDict注解
            "private\\s+(\\w+(?:<[\\w\\.]+(?:,\\s*[\\w\\.]+)*>)?)\\s+(\\w+)\\s*;"  // 字段声明
        );

        Matcher matcher = fieldPattern.matcher(content);
        
        while (matcher.find()) {
            String comment = matcher.group(1);  // 注释内容
            String annotation = matcher.group(2);  // 注解内容
            String type = matcher.group(3);
            String name = matcher.group(4);

            // 解析注解属性（如果有）
            Map<String, String> annotationAttrs = annotation != null ? parseAnnotation(annotation) : new HashMap<>();
            
            // 处理List类型
            if (type.contains("List<")) {
                Pattern genericPattern = Pattern.compile("List<([\\w\\.]+)>");
                Matcher genericMatcher = genericPattern.matcher(type);
                if (genericMatcher.find()) {
                    String genericType = genericMatcher.group(1);
                    String fieldRemark = "";
                    
                    // 尝试从不同来源获取描述信息
                    if (annotationAttrs.containsKey("desc")) {
                        fieldRemark = annotationAttrs.get("desc");
                    } else if (comment != null) {
                        fieldRemark = extractDescriptionFromComment(comment);
                    }
                    
                    addListField(fields, name, genericType, fieldRemark, imports, filePath);
                }
            } else {
                Map<String, String> field = new HashMap<>();
                field.put("is_encrypt", "false");
                field.put("mapping", "");
                field.put("default", "");
                field.put("is_must", "false");
                field.put("name", name);
                
                // 设置字段长度
                String length = annotationAttrs.getOrDefault("length", "-1");
                field.put("length", length);
                
                // 设置描述信息
                String remark = "";
                if (annotationAttrs.containsKey("desc")) {
                    remark = annotationAttrs.get("desc");
                } else if (comment != null) {
                    remark = extractDescriptionFromComment(comment);
                }
                field.put("remark", remark);
                
                field.put("source", "");
                field.put("type", convertType(type));
                
                // 设置错误码和消息
                if (annotationAttrs.containsKey("errorCode")) {
                    field.put("error_code", annotationAttrs.get("errorCode"));
                }
                if (annotationAttrs.containsKey("message")) {
                    field.put("message", annotationAttrs.get("message"));
                }
                
                fields.add(field);
            }
        }

        return fields;
    }

    private String extractDescriptionFromComment(String comment) {
        if (comment == null) {
            return "";
        }
        
        // 移除多余的空格和换行符
        comment = comment.trim().replaceAll("\\s+", " ");
        
        // 如果注释包含竖线，取竖线后面的英文描述
        if (comment.contains("|")) {
            String[] parts = comment.split("\\|");
            if (parts.length > 1) {
                return parts[0].trim() + " | " + parts[1].trim();
            }
        }
        
        return comment;
    }

    private Map<String, String> parseAnnotation(String annotation) {
        if (annotation == null) {
            return new HashMap<>();
        }
        Map<String, String> attrs = new HashMap<>();
        Pattern attrPattern = Pattern.compile("(\\w+)\\s*=\\s*\"([^\"]*)\"");
        Matcher attrMatcher = attrPattern.matcher(annotation);
        while (attrMatcher.find()) {
            attrs.put(attrMatcher.group(1), attrMatcher.group(2));
        }
        return attrs;
    }

    private void addListField(List<Map<String, String>> fields, String name, String genericType, String fieldRemark, Map<String, String> imports, String filePath) throws Exception {
        // 添加List字段
        Map<String, String> listField = new HashMap<>();
        listField.put("is_encrypt", "false");
        listField.put("mapping", "rec");
        listField.put("default", "");
        listField.put("is_must", "false");
        listField.put("name", name);
        listField.put("length", "-1");
        listField.put("remark", fieldRemark);
        listField.put("source", "");
        listField.put("type", "Array");
        fields.add(listField);

        // 解析泛型类型的字段
        String fullClassName = imports.getOrDefault(genericType, genericType);
        String genericClassPath = findJavaFile(fullClassName, filePath);
        
        if (genericClassPath != null) {
            String genericContent = new String(Files.readAllBytes(Paths.get(genericClassPath)));
            
            // 解析泛型类中的字段
            Pattern fieldPattern = Pattern.compile(
                "(?:/\\*+\\s*([^*]*?)\\s*\\*+/\\s*)?" +  // 可选的块注释
                "(?:@ECPDict\\s*\\(([^)]*)\\)\\s*)?" +   // 可选的@ECPDict注解
                "private\\s+(\\w+(?:<[\\w\\.]+(?:,\\s*[\\w\\.]+)*>)?)\\s+(\\w+)\\s*;"  // 字段声明
            );
            
            Matcher matcher = fieldPattern.matcher(genericContent);
            while (matcher.find()) {
                String comment = matcher.group(1);
                String annotation = matcher.group(2);
                String fieldType = matcher.group(3);
                String fieldName = matcher.group(4);
                
                Map<String, String> annotationAttrs = annotation != null ? parseAnnotation(annotation) : new HashMap<>();
                
                Map<String, String> field = new HashMap<>();
                field.put("is_encrypt", "false");
                field.put("mapping", "");
                field.put("default", "");
                field.put("is_must", "false");
                field.put("name", name + "." + fieldName);
                
                // 设置字段长度
                String length = annotationAttrs.getOrDefault("length", "-1");
                field.put("length", length);
                
                // 设置描述信息
                String fieldDesc = "";
                if (annotationAttrs.containsKey("desc")) {
                    fieldDesc = annotationAttrs.get("desc");
                } else if (comment != null) {
                    fieldDesc = extractDescriptionFromComment(comment);
                }
                field.put("remark", fieldDesc);
                
                field.put("source", "");
                field.put("type", convertType(fieldType));
                
                // 设置错误码和消息
                if (annotationAttrs.containsKey("errorCode")) {
                    field.put("error_code", annotationAttrs.get("errorCode"));
                }
                if (annotationAttrs.containsKey("message")) {
                    field.put("message", annotationAttrs.get("message"));
                }
                
                fields.add(field);
            }
        }
    }

    private String findJavaFile(String fullClassName, String currentFilePath) {
        try {
            // 获取当前文件所在的项目根目录
            File currentFile = new File(currentFilePath);
            File projectRoot = findProjectRoot(currentFile);
            if (projectRoot == null) {
                return null;
            }

            // 将完整类名转换为文件路径
            String classPath = fullClassName.replace('.', '/') + ".java";
            
            // 在src目录下查找Java文件
            File srcDir = new File(projectRoot, "src");
            if (srcDir.exists()) {
                File[] srcDirs = srcDir.listFiles(File::isDirectory);
                if (srcDirs != null) {
                    for (File dir : srcDirs) {
                        File javaFile = new File(dir, classPath);
                        if (javaFile.exists()) {
                            return javaFile.getAbsolutePath();
                        }
                    }
                }
            }

            // 如果在src目录下找不到，尝试直接在当前目录的同级目录中查找
            File parentDir = currentFile.getParentFile();
            if (parentDir != null) {
                String simpleClassName = fullClassName.substring(fullClassName.lastIndexOf('.') + 1);
                File targetFile = new File(parentDir, simpleClassName + ".java");
                if (targetFile.exists()) {
                    return targetFile.getAbsolutePath();
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    private File findProjectRoot(File file) {
        File current = file.getParentFile();
        while (current != null) {
            if (new File(current, "pom.xml").exists() || 
                new File(current, "build.gradle").exists()) {
                return current;
            }
            current = current.getParentFile();
        }
        return null;
    }

    private void addBasicFields(List<Map<String, String>> fields) {
        // 添加traceId
        Map<String, String> traceId = new HashMap<>();
        traceId.put("is_encrypt", "false");
        traceId.put("mapping", "");
        traceId.put("default", "");
        traceId.put("is_must", "false");
        traceId.put("name", "traceId");
        traceId.put("length", "-1");
        traceId.put("remark", "日志id");
        traceId.put("source", "");
        traceId.put("type", "String");
        fields.add(traceId);

        // 添加其他基本字段...
        String[][] basicFields = {
            {"txSts", "1", "交易状态|transaction status", "String", "", "txSts"},
            {"rspMsgCd", "-1", "返回码", "String"},
            {"rspMsgInf", "-1", "返回信息", "String"},
            {"jrnNo", "32", "合作伙伴流水号|Partner serial number", "String", "TRSP0001", ""},
            {"serviceTime", "-1", "服务器时间", "String"}
        };

        for (String[] field : basicFields) {
            Map<String, String> map = new HashMap<>();
            map.put("is_encrypt", "false");
            map.put("mapping", "");
            map.put("default", "");
            map.put("is_must", "false");
            map.put("name", field[0]);
            map.put("length", field[1]);
            map.put("remark", field[2]);
            map.put("source", "");
            map.put("type", field[3]);
            if (field.length > 4 && !field[4].isEmpty()) {
                map.put("error_code", field[4]);
            }
            if (field.length > 5 && !field[5].isEmpty()) {
                map.put("message", field[5]);
            }
            fields.add(map);
        }
    }

    private String convertType(String javaType) {
        if (javaType.startsWith("List<")) {
            return "Array";
        }
        
        switch (javaType) {
            case "String":
                return "String";
            case "Integer":
            case "Long":
            case "int":
            case "long":
                return "Number";
            case "BigDecimal":
            case "YGAmt":
                return "Amt";
            case "List":
                return "Array";
            default:
                return "String";
        }
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> {
            try {
                UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
            } catch (Exception e) {
                e.printStackTrace();
            }
            new JsonGeneratorWindow();
        });
    }
} 